/// 使用一个单独的trait
trait DynTra {
    fn liest(&self) {
        println!("woshi 1");
    }
}


/// 定义两个struct Teacher和Student,两个struct都空实现了dynTra
struct Teacher;

struct Student;

impl DynTra for Teacher{}

impl DynTra for Student{}


/// 通过静态分发
fn sta_fun(t:&impl DynTra) {
   t.liest();
}
fn sta_fun1<T:DynTra>(t:&T) {
    t.liest();
 }


 fn sta_fun2(t : impl DynTra) -> impl  DynTra{
    Teacher
 }

/// 通过动态分发
fn dyn_fun(t:&dyn DynTra)  {
   t.liest();
 }
 fn dyn_fun1() -> Box<dyn DynTra> {
    Box::new(Teacher)
 }
 fn dyn_fun2(t:Box<dyn DynTra>)  {
    t.liest();
 }
 #[cfg(test)]
mod test {
    use super::*;


    // 使用静态分发
    #[test]
    fn test() {
        let techer = Teacher;
        sta_fun(&techer);
    }

    // 使用动态分发
    #[test]
    fn test1() {
        let techer = Teacher;
        dyn_fun(&techer);
        let t = dyn_fun1();
        t.liest();
    }

    // 定义静态和动态变量
    #[test]
    fn test2() {
        // 不允许，只允许出现在参数和返回参数中
        // let s1 :impl DynTra = Teacher;

        let s2 : Box<dyn DynTra> = Box::new(Teacher);
    }
}